<script setup lang="ts">
import FileItem from '@/components/material/file.vue'
import Preview from '@/components/material/preview.vue'
import useAppStore from '@/stores/modules/app'

const { getImageUrl } = useAppStore()

const props = defineProps({
  modelValue: {
    type: [String, Array],
    default: () => []
  },
  // 上传文件类型
  type: {
    type: String,
    default: 'image'
  },
  // 是否支持多选
  multiple: {
    type: Boolean,
    default: true
  },
  // 多选时最多选择几条
  limit: {
    type: Number,
    default: 10
  },
  // 上传时的额外参数
  data: {
    type: Object,
    default: () => ({})
  },
  // 是否显示上传进度
  showProgress: {
    type: Boolean,
    default: true
  },
  // 选择器尺寸
  size: {
    type: String,
    default: '100px'
  },
  // 选择器尺寸-宽度（不传则是使用size
  width: {
    type: String,
    default: ''
  },
  // 选择器尺寸-高度（不传则是使用size
  height: {
    type: String,
    default: ''
  },
  // 禁用选择
  disabled: {
    type: Boolean,
    default: false
  },
  //选择的url排出域名
  excludeDomain: {
    type: Boolean,
    default: false
  }
})

const { disabled, limit, modelValue } = toRefs(props)

const emits = defineEmits(['change', 'update:modelValue'])

const previewUrl = ref('')
const showPreview = ref(false)
const fileList = ref<any[]>([])
const showUpload = computed(() => {
  return props.limit - fileList.value.length > 0
})

watch(
  modelValue,
  (val: any[] | string) => {
    fileList.value = Array.isArray(val) ? val : val == '' ? [] : [val]
  },
  {
    immediate: true
  }
)

const deleteImg = (index: number) => {
  fileList.value.splice(index, 1)
  handleChange()
}

const handleChange = () => {
  const valueImg = props.limit != 1 ? fileList.value : fileList.value[0] || ''
  emits('update:modelValue', valueImg)
  emits('change', valueImg)
}

const handlePreview = (url: string) => {
  previewUrl.value = url
  showPreview.value = true
}

const allSuccess = (val: any) => {
  fileList.value.push(val.data.uri)
  emits('update:modelValue', fileList.value)
  emits('change')
}
</script>

<template>
  <div class="flex flex-wrap">
    <div
      v-for="(element, index) in fileList"
      :key="index"
      class="material-preview"
      :class="{
        'is-disabled': disabled,
        'is-one': limit == 1
      }"
    >
      <del-wrap @close="deleteImg(index)">
        <file-item
          :uri="excludeDomain ? getImageUrl(element) : element"
          :file-size="size"
          :width="width"
          :height="height"
          :type="type"
        ></file-item>
      </del-wrap>
      <div class="operation-btns text-xs text-center" v-if="type == 'image'">
        <span @click.stop="handlePreview(element)">查看</span>
      </div>
      <div class="operation-btns text-xs text-center" v-if="type == 'video'">
        <span @click.stop="handlePreview(element)">查看</span>
      </div>
    </div>
    <upload
      v-if="showUpload"
      :type="type"
      :multiple="multiple"
      :limit="limit"
      :data="data"
      :showProgress="showProgress"
      @success="allSuccess"
    >
      <div
        class="upload-btn"
        :style="{
          width: width || size,
          height: height || size
        }"
      >
        <icon :size="25" name="el-icon-Plus" />
        <span>添加</span>
      </div>
    </upload>

    <preview v-model="showPreview" :url="previewUrl" :type="type" />
  </div>
</template>

<style scoped lang="scss">
.material-preview {
  position: relative;
  border-radius: 4px;
  cursor: pointer;
  margin-right: 8px;
  margin-bottom: 8px;
  box-sizing: border-box;
  float: left;
  &.is-disabled {
    cursor: not-allowed;
  }
  &.is-one {
    margin-bottom: 0;
  }
  &:hover {
    .operation-btns {
      display: block;
    }
  }
  .operation-btns {
    display: none;
    position: absolute;
    bottom: 0;
    border-radius: 4px;
    width: 100%;
    line-height: 2;
    color: #fff;
    background-color: rgba(0, 0, 0, 0.3);
  }
}
.upload-btn {
  @apply text-tx-secondary box-border rounded border-br border-dashed border flex flex-col justify-center items-center;
}
</style>
